﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Diagnostics.Contracts;

namespace SimpleIR
{
	public static class OpCode
	{
		/// <summary>
		/// An enumeration of all of the operation codes that are used in the Intermediate Language.
		/// </summary>
		public enum Op
		{
			//////////////
			//Control Flow
			BranchU, /*Unconditional branch*/
			BranchC, /*Branch on condition*/
			Switch,  /*Switch*/
			Throw,   /*Throw*/
			Return,  /*Return*/

			//////////////
			//Method Calls and Allocation
			Call,       /*Call a method with a fixed named target*/
			CallVirt,   /*Call a method on a pointer with virtual method resolution*/
			AllocCons,  /*Allocate a new block of memory for the given type and call the given constructor on it*/
			
			//////////////
			//Primitive Compare
			PrimEQ,     /*Equality compare*/
			Less,       /*Less than*/
			LessU,       /*Less than (may be unordered)*/
			LessEQ,     /*Less than or equal*/
			LessEQU,     /*Less than or equal unordered*/
			Greater,    /*Greater than*/
			GreaterU,    /*Greater than unordered*/
			GreaterEQ,  /*Greater than or equal*/
			GreaterEQU,  /*Greater than or equal unordered*/
			
			//////////////
			//Primitive Arith Operations
			Add,   /*Add values*/
			AddU,  /*Add values unsigned*/
			Div,   /*Div values*/
			DivU,  /*Div values unsigned*/
			Mult,  /*Mult values (may be unsigned)*/
			MultU, /*Mult values*/
			Neg,  /*Numeric Negate the value*/
			Rem,  /*Rem values (may be unsigned)*/
			RemU,  /*Rem values*/
			Sub,  /*Sub values (may be unsigned)*/
			SubU,  /*Sub values*/

			//////////////
			//Primitive Bitwise Operations
			And,   /*And the values*/
			Or,    /*Or the values*/
			Not,   /*Bitwise Negate the value*/
			Shl,   /*Shift left on value*/
			Shr,   /*Shift right on value*/
			ShrU,  /*Shift right on value unsigned for shr logical*/
			Xor,   /*Xor the values*/
			Conv,  /*Convert the value to the given new type*/

			//////////////
			//Load/Store
			LoadFromLocal,  /*Load a value from a local var to the stack*/
			StoreToLocal,   /*Store a value from the stack to a local var*/
			LoadFromGlobal, /*Load a value from a global var to the stack*/
			StoreToGlobal,  /*Store a value from the stack to a global var*/

			//////////////
			//Load/Store Through Pointers
			ArrayLoad,          /*Read a value at an array index*/
			ArrayStore,         /*Store a value to an array index*/
			ArrayLength,        /*Read the length value from an array*/
			IndirectRead,       /*Read a value through a reference*/
			IndirectWrite,      /*Store a value through a reference*/
			IndirectInitialize,	/*Write default intialization values through reference to struct/class*/
			LoadStructField,	/*Load the given field from the struct on the top of the stack*/

			//////////////
			//Pointer Creation and Indexing
			LoadLocalAddr,            /*Take the address of a local variable*/
			LoadGlobalAddr,           /*Take the address of global name*/
			IndexRefAddrByField,      /*Index the reference (or pointer) address by the given field, also knowns the index on the stack that holds the pointer to use as the base*/
			IndexRefAddrByArrayIndex, /*Index the given reference (or pointer) address (to an array) by the given index, also knowns the index on the stack that holds the pointer to use as the base*/
			LoadFuncPtr,              /*Get the token for a specific function*/
			LoadVFuncPtr,             /*Get the token for a function and method lookup on the pointer on top of the stack*/

			LoadMemberField,  /*Load a value from a member field.*/
			StoreMemberField, /*Store a value to a member field.*/

			//////////////
			//Pointer Compare
			DerefableEQ,     /*Equality of the pointers (or references)*/
			NonNull,		 /*Is the pointer on top of the stack non-null*/

			//////////////
			//Type Operations
			Box,       /*Box the valuetype on the top of the stack*/
			UnBox,     /*Unbox the boxed object on top of the stack*/
			Cast,      /*Cast with throw to given type*/
			IsInst,    /*Cast without throw to given type (null if not possible)*/
			Constrain, /*Before a vcall do needed contraint of reciver argument*/
			
			//////////////
			//Misc Operations
			Pop,        /*Pop the top of the stack*/
			Dup,        /*Duplicate the element on the top of the stack*/
			PushNull,   /*Push the null literal on the stack*/
			PushInt,    /*Push the given int literal on the stack*/
			PushFloat,  /*Push the given float literal on the stack*/
			PushString  /*Push the given string literal on the stack*/
		}
	}
}
